<template>
  <div>
    <!-- 第一步 - 创建任务 -->
    <div class="task-container">
      <el-form ref="taskForm" :model="taskData" :rules="rules">
      <!-- 任务基本信息 -->
      <div class="data-show">
        <!-- 头部标题 -->
        <div class="data-actions">
          <h3>任务基本信息</h3>
        </div>
        <!-- 内容区 -->
        <div class="data-table">
          <!-- 通用布局行 -->
          <div class="common-row row-between">
            <!-- 配置项 - 任务名称 -->
            <div class="common-item item-5">
              <label class="condition-label">任务名称</label>
              <el-form-item class="condition-input" prop="name">
                <el-input type="text" :disabled="taskData.done" placeholder="请输入任务名称" v-model="taskData.name" />
              </el-form-item>
            </div>
            <!-- 配置项 - 平台 -->
            <div class="common-item item-5">
              <label class="condition-label">社交平台</label>
              <el-form-item class="condition-input" prop="system">
                <el-select :disabled="taskData.done" v-model="taskData.system" clearable placeholder="请选择平台">
                  <el-option v-for="(item, index) in systems" :key="index" :label="item.label" :value="item.value"></el-option>
                </el-select>
              </el-form-item>
            </div>
            <!-- 配置项 - 类型 -->
            <!-- <div class="common-item item-3">
              <label class="condition-label">任务类型</label>
              <el-form-item class="condition-input" prop="system">
                <el-select :disabled="taskData.done" v-model="taskData.type" clearable placeholder="请选择类型">
                  <el-option v-for="(item, index) in types" :key="index" :label="item.label" :value="item.value"></el-option>
                </el-select>
              </el-form-item>
            </div> -->
          </div>
          <!-- 通用布局行 -->
          <div class="common-row">
            <div class="common-item item-10">
              <label class="condition-label">任务描述</label>
              <el-form-item class="condition-input" prop="description">
                <el-input :disabled="taskData.done" v-model="taskData.description" maxlength="100" type="textarea" show-word-limit :rows="4" resize="none" placeholder="请输入任务描述" />
              </el-form-item>
            </div>
          </div>
        </div>
      </div>
      <!-- 公钥提取-->
      <div class="data-show">
        <!-- 头部标题 -->
        <div class="data-actions data-title-between">
          <h3>密钥协商(接收)</h3>
        </div>
        <!-- 内容区 -->
        <div class="data-table">
          <!-- 通用布局行 -->
          <div class="common-row row-between">
            <!-- 配置项 - 发布用户 -->
            <div class="common-item item-5">
              <label class="condition-label">接收用户</label>
                <el-form-item class="condition-input" prop="userID">
                  <el-input :disabled="taskData.done" type="text" placeholder="请输入接收用户" v-model="taskData.userID" />
                </el-form-item>
            </div>
            <!-- 配置项 - 目标用户 -->
            <div class="common-item item-5">
              <label class="condition-label">发布用户</label>
              <el-form-item class="condition-input" prop="targetUserId">
                <el-input :disabled="taskData.done" type="text" placeholder="请输入发布用户" v-model="taskData.targetUserId" />
              </el-form-item>
            </div>
          </div>
          <!-- 通用布局行 -->
          <div class="common-row row-between">
            <!-- 配置项 - 算法类别 -->
            <div class="common-item item-5">
              <label class="condition-label">算法模块</label>
              <el-form-item class="condition-input" prop="keyType">
                <el-select :disabled="taskData.done" v-model="taskData.keyType" clearable placeholder="请选择算法模块">
                  <el-option v-for="(item, index) in keyTypes" :label="item.label" :value="item.value" :key="index"></el-option>
                </el-select>
              </el-form-item>
            </div>
            <!-- 配置项 - 参数文件 -->
            <div class="common-item item-5">
              <label class="condition-label">选择参数</label>
              <el-form-item class="condition-input" prop="config">
                <el-select :disabled="taskData.done" v-model="taskData.config" clearable placeholder="请选择参数文件">
                  <el-option v-for="(item, index) in configs" :label="item.label" :value="item.value" :key="index"></el-option>
                </el-select>
              </el-form-item>
            </div>
          </div>
          <!-- 通用布局行 - 公钥密文 -->
          <div class="common-row">
            <div class="common-item item-10" :class="{'item-upload': uploadObj.keyOneTextFilePath.showFileList}">
              <el-tooltip content="切换上传方式" placement="top">
                <label class="condition-label condition-label-change" @click="changeUploadType('keyOneTextFilePath', taskData)">密钥密文</label>
              </el-tooltip>
              <el-form-item class="condition-input" prop="keyOneTextFilePath">
                <el-upload
                  drag
                  class="upload"
                  :disabled="taskData.done"
                  v-if="uploadObj.keyOneTextFilePath.isUploadType"
                  :ref="uploadObj.uploadRef('keyOneTextFilePath')"
                  :action="uploadObj.uploadUrl"
                  :limit="1"
                  :show-file-list="uploadObj.keyOneTextFilePath.showFileList"
                  :before-upload="uploadObj.beforeUpload('keyOneTextFilePath')"
                  :on-success="uploadObj.onSuccess('keyOneTextFilePath', taskData, taskForm)"
                  :on-progress="uploadObj.onProgress('keyOneTextFilePath')"
                  :on-error="uploadObj.onError('keyOneTextFilePath')"
                  :on-remove="uploadObj.onRemove('keyOneTextFilePath')"
                >
                  <transition name="upload">
                    <div class="upload-empty" v-if="!taskData.keyOneTextFilePath">
                      <i class="iconfont icon-icon_update upload-icon"></i>
                      <p class="upload-des">拖拽文件至此或点击上传</p>
                    </div>
                    <div class="upload-content" v-else>
                      <i class="iconfont icon-daimawenjian-mian upload-icon"></i>
                      <p class="upload-des">{{ uploadObj.keyOneTextFilePath.fileName }}</p>
                    </div>
                  </transition>
                </el-upload>
                <el-input v-else :disabled="taskData.done" type="textarea" @input="clearData('keyOneTextFilePath', taskData)" @change="createBlobTxt($event, 'keyOneTextFilePath', taskData, taskForm)" v-model="uploadObj.keyOneTextFilePath.text" show-word-limit :rows="5" resize="none" placeholder="请输入文本" />
              </el-form-item>
            </div>
          </div>
        </div>
      </div>
      <transition name="upload">
        <!-- 按钮部分 -->
        <div class="btn-groups" v-if="!taskData.done">
          <button type="button" class="btn btn-normal" @click="handleCancel">取消</button>
          <button :disabled="taskData.createFlag" type="button" class="btn" @click="handleCreate">接收</button>
        </div>
        <!-- 展示提取的公钥 -->
        <div class="data-show" v-else>
          <!-- 标题 -->
          <div class="data-actions">
            <h3>接收协商密钥参数展示</h3>
          </div>
          <div class="data-table data-table-scroll">
            <p class="text-container">
              {{ taskData.keyOne }}
            </p>
          </div>
        </div>
      </transition>
      </el-form>


      <!-- 第二步 - 共享密钥 -->
      <el-form ref="shareKeyForm" :model="shareKey" :rules="rules" v-if="taskData.done">
      <transition name="upload">
        <!-- 底部的按钮 -->
        <div class="btn-groups" v-if="!shareKey.done">
          <button type="button" class="btn btn-normal" @click="handleCancel">取消</button>
          <button type="button" :disabled="shareKey.btnFlag" class="btn" @click="handleShareKey">返回协商密钥参数</button>
        </div>
        <!-- 展示提取的私钥 -->
        <el-row v-else :gutter="20">
          <el-col :span="12">
            <div class="data-show">
              <!-- 标题 -->
              <div class="data-actions data-title-between">
                <h3>协商密钥参数密文</h3>
                <div class="data-title-actions">
                  <span class="action aniTxtBtn" @click="copyText('keyTwoText', shareKey, '密文为空，请稍后重试或联系管理员')">复制</span>
                  <span class="action aniTxtBtn" @click="downText('keyTwoText', shareKey, '未提供密文，请稍后重试或联系管理员', 'keyOneText.json')">下载</span>
                </div>
              </div>
              <div class="data-table data-table-scroll">
                <p class="text-container">
                  {{ changeJSON(shareKey.keyTwoText) }}
                </p>
              </div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="data-show">
                <!-- 标题 -->
                <div class="data-actions data-title-between">
                  <h3>协商密钥</h3>
                </div>
                <div class="data-table data-table-scroll">
                  <p class="text-container">
                    {{ shareKey.keyThree }}
                  </p>
                </div>
              </div>
          </el-col>
        </el-row>
      </transition>
      </el-form>


      <!-- 第三步 - 提取签名 -->
      <el-form ref="signForm" :model="signData" :rules="rules" v-if="shareKey.done">
      <div class="data-show">
        <!-- 标题 -->
        <div class="data-actions">
          <h3>签名认证、信息提取</h3>
        </div>
        <!-- 内容区 -->
        <div class="data-table">
          <!-- 通用布局行 - 媒体类型、参数文件 -->
          <div class="common-row row-between">
            <!-- 配置项 - 平台 -->
            <div class="common-item item-5">
              <label class="condition-label">参数文件</label>
              <el-form-item class="condition-input" prop="parameter">
                <el-select :disabled="signData.done" v-model="signData.parameter" clearable placeholder="请选择参数文件">
                  <el-option v-for="(item, index) in parameters" :key="index" :label="item.label" :value="item.value"></el-option>
                </el-select>
              </el-form-item>
            </div>
            <!-- 配置项 - 类型 -->
            <div class="common-item item-5">
              <label class="condition-label">媒体类型</label>
              <el-form-item class="condition-input" prop="module">
                <el-select @change="moduleChange" :disabled="signData.done" v-model="signData.module" clearable placeholder="请选择类型">
                  <el-option v-for="(item, index) in modules" :key="index" :label="item.label" :value="item.value"></el-option>
                </el-select>
              </el-form-item>
            </div>
          </div>
          <!-- 通用布局行 - 签名文件上传 -->
          <div class="common-row">
            <div class="common-item item-10" :class="{'item-upload': uploadObj.signatureFilePath.showFileList}">
              <el-tooltip content="切换上传方式" placement="top">
                <label class="condition-label condition-label-change" @click="changeUploadType('signatureFilePath', signData)">签名文件</label>
              </el-tooltip>
              <el-form-item class="condition-input" prop="signatureFilePath">
                <el-upload
                  v-if="uploadObj.signatureFilePath.isUploadType"
                  class="upload"
                  :disabled="signData.done"
                  :ref="uploadObj.uploadRef('signatureFilePath')"
                  drag
                  :action="uploadObj.uploadUrl"
                  :limit="1"
                  :show-file-list="uploadObj.signatureFilePath.showFileList"
                  :before-upload="uploadObj.beforeUpload('signatureFilePath')"
                  :on-success="uploadObj.onSuccess('signatureFilePath', signData, signForm)"
                  :on-progress="uploadObj.onProgress('signatureFilePath')"
                  :on-error="uploadObj.onError('signatureFilePath')"
                  :on-remove="uploadObj.onRemove('signatureFilePath')"
                >
                  <transition name="upload">
                    <div class="upload-empty" v-if="!signData.signatureFilePath">
                      <i class="iconfont icon-icon_update upload-icon"></i>
                      <p class="upload-des">拖拽文件至此或点击上传</p>
                    </div>
                    <div class="upload-content" v-else>
                      <i class="iconfont icon-daimawenjian-mian upload-icon"></i>
                      <p class="upload-des">{{ uploadObj.signatureFilePath.fileName }}</p>
                    </div>
                  </transition>
                </el-upload>
                <el-input :disabled="signData.done" v-else type="textarea" @input="clearData('signatureFilePath', signData)" @change="createBlobTxt($event, 'signatureFilePath', signData, signForm)" v-model="uploadObj.signatureFilePath.text" show-word-limit :rows="5" resize="none" placeholder="请输入文本" />
              </el-form-item>
            </div>
          </div>
          <!-- 通用布局行 - prompt上传 -->
          <div class="common-row">
            <div class="common-item item-10" :class="{'item-upload': uploadObj.promptFilePath.showFileList}">
              <el-tooltip content="切换上传方式" placement="top">
                <label class="condition-label condition-label-change" @click="changeUploadType('promptFilePath', signData)">提示词</label>
              </el-tooltip>
              <el-form-item class="condition-input" prop="promptFilePath">
                <el-upload
                  v-if="uploadObj.promptFilePath.isUploadType"
                  class="upload"
                  :disabled="signData.done"
                  :ref="uploadObj.uploadRef('promptFilePath')"
                  drag
                  :action="uploadObj.uploadUrl"
                  :limit="1"
                  :show-file-list="uploadObj.promptFilePath.showFileList"
                  :before-upload="uploadObj.beforeUpload('promptFilePath')"
                  :on-success="uploadObj.onSuccess('promptFilePath', signData, signForm)"
                  :on-progress="uploadObj.onProgress('promptFilePath')"
                  :on-error="uploadObj.onError('promptFilePath')"
                  :on-remove="uploadObj.onRemove('promptFilePath')"
                >
                  <transition name="upload">
                    <div class="upload-empty" v-if="!signData.promptFilePath">
                      <i class="iconfont icon-icon_update upload-icon"></i>
                      <p class="upload-des">拖拽文件至此或点击上传</p>
                    </div>
                    <div class="upload-content" v-else>
                      <i class="iconfont icon-daimawenjian-mian upload-icon"></i>
                      <p class="upload-des">{{ uploadObj.promptFilePath.fileName }}</p>
                    </div>
                  </transition>
                </el-upload>
                <el-input :disabled="signData.done" v-else type="textarea" @input="clearData('promptFilePath', signData)" @change="createBlobTxt($event, 'promptFilePath', signData, signForm)" v-model="uploadObj.promptFilePath.text" show-word-limit :rows="5" resize="none" placeholder="请输入文本" />
              </el-form-item>
            </div>
          </div>
          <!-- 通用布局行 - 密钥key -->
          <!-- <div class="common-row">
            <div class="common-item item-10" :class="{'item-upload': uploadObj.keyFilePath.showFileList}">
              <label class="condition-label">协商密钥</label>
              <el-form-item class="condition-input" prop="keyFilePath">
                <el-upload
                  class="upload"
                  :disabled="signData.done"
                  :ref="uploadObj.uploadRef('keyFilePath')"
                  drag
                  :action="uploadObj.uploadUrl"
                  :limit="1"
                  :show-file-list="uploadObj.keyFilePath.showFileList"
                  :before-upload="uploadObj.beforeUpload('keyFilePath')"
                  :on-success="uploadObj.onSuccess('keyFilePath', signData)"
                  :on-progress="uploadObj.onProgress('keyFilePath')"
                  :on-error="uploadObj.onError('keyFilePath')"
                  :on-remove="uploadObj.onRemove('keyFilePath')"
                >
                  <transition name="upload">
                    <div class="upload-empty" v-if="!signData.keyFilePath">
                      <i class="iconfont icon-icon_update upload-icon"></i>
                      <p class="upload-des">拖拽文件至此或点击上传</p>
                    </div>
                    <div class="upload-content" v-else>
                      <i class="iconfont icon-daimawenjian-mian upload-icon"></i>
                      <p class="upload-des">{{ uploadObj.keyFilePath.fileName }}</p>
                    </div>
                  </transition>
                </el-upload>
              </el-form-item>
            </div>
          </div> -->
          <!-- 通用布局行 - 载体图片 -->
          <div class="common-row" key="stegoFilePath">
            <!-- <span v-if="signData.stegoFilePath">{{ signData.stegoFilePath }}</span>
            <span v-else>{{ signData.stegoFilePath }}</span> -->
            <div class="common-item item-10" :class="{'item-upload': uploadObj.stegoFilePath.showFileList}">
              <label class="condition-label">载密文件</label>
              <el-form-item class="condition-input" prop="stegoFilePath">
                <el-upload
                  class="upload"
                  :disabled="signData.done"
                  :ref="uploadObj.uploadRef('stegoFilePath')"
                  drag
                  :action="uploadObj.uploadUrl"
                  :limit="1"
                  :show-file-list="uploadObj.stegoFilePath.showFileList"
                  :before-upload="uploadObj.beforeUpload('stegoFilePath')"
                  :on-success="uploadObj.onSuccess('stegoFilePath', signData, signForm)"
                  :on-progress="uploadObj.onProgress('stegoFilePath')"
                  :on-error="uploadObj.onError('stegoFilePath')"
                  :on-remove="uploadObj.onRemove('stegoFilePath')"
                >
                  <transition name="upload">
                    <div class="upload-empty" v-if="!signData.stegoFilePath">
                      <i class="iconfont icon-icon_update upload-icon"></i>
                      <p class="upload-des">拖拽文件至此或点击上传</p>
                    </div>
                    <div class="upload-content" v-else>
                      <i class="iconfont icon-daimawenjian-mian upload-icon"></i>
                      <p class="upload-des">{{ uploadObj.stegoFilePath.fileName }}</p>
                    </div>
                  </transition>
                </el-upload>
              </el-form-item>
            </div>
          </div>
        </div>
      </div>
      <transition name="upload">
        <!-- 底部的按钮 -->
        <div class="btn-groups" v-if="!signData.done">
          <button type="button" class="btn btn-normal" @click="handleCancel">取消</button>
          <button type="button" :disabled="signData.btnFlag" class="btn" @click="handleSign">认证和提取</button>
        </div>
        <div v-else>
          <el-row :gutter="20">
            <el-col :span=12>
              <div class="data-show">
                <!-- 标题 -->
                <div class="data-actions">
                  <h3>认证结果</h3>
                </div>
                <div class="data-table data-table-scroll">
                  <p class="text-container">
                    {{ signData.verifyResult }}
                  </p>
                </div>
              </div>
            </el-col>
            <el-col :span=12>
              <div class="data-show">
                <!-- 标题 -->
                <div class="data-actions data-title-between">
                  <h3>秘密消息</h3>
                  <div class="data-title-actions">
                    <span class="action aniTxtBtn" @click="downloadFile">下载</span>
                  </div>
                </div>
                <div class="data-table data-table-scroll">
                  <el-image class="file-image" v-if="getModuleShow(signData.extractingMessageFilePath, signData.module) === '图像'" :src="signData.messageFile" fit="contain" :preview-src-list="[signData.messageFile]" />
                  <!-- <p v-else-if="signData.module === '文本'" class="text-container">
                    {{ signData.messageFile }}
                  </p> -->
                  <p class="text-container" v-else-if="getModuleShow(signData.extractingMessageFilePath, signData.module) === '文本'">
                    {{ signData.messageFile }}
                  </p>
                  <div class="audio-container audio-show" v-else>
                    <i class="iconfont icon-swticonyinle audio-icon"></i>
                    <p class="audio-filename">{{ signData.messageFile }}</p>
                  </div>
                  <!-- <div class="audio-container" v-else>
                    <i class="iconfont icon-swticonyinle audio-icon"></i>
                    <audio class="audio" :src="signData.messageFile" controls></audio>
                  </div> -->
                </div>
              </div>
            </el-col>
          </el-row>
        </div>
      </transition>
      </el-form>
    </div>
  </div>
</template>
<script setup>
import useAppStore from '@/stores/app';
import { ref, computed, watch, onActivated } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { API } from '@/utils/status.js';
import { ElMessage } from 'element-plus';
import * as uploadApi from '@/api/file';
import * as request from '@/api/steganography';
import * as rule from '@/utils/rules';

const router = useRouter();
const route = useRoute();
const systems = API.steganography.systems;
const parameters = API.steCommon.parameters;
const modules = API.steCommon.modules;
const types = [
  { value: 0, label: '类型1' },
  { value: 1, label: '类型2' }
];
const configs = [
  { value: 'config1', label: 'ECC参数文件' },
  { value: 'config2', label: 'RSA参数文件' }
];
const keyTypes = API.publicSteg.keyTypes;

const defaultTaskData = {
  done: false,
  createFlag: false,
  id: null,
  name: '',
  description: '',
  system: null,
  type: null,
  keyType: null,
  config: null,
  userID: null,
  targetUserId: null,
  // 上传公钥密文路径
  keyOneTextFilePath: null,
  keyOne: null
};
const defaultShareKey = {
  done: false,
  btnFlag: false,
  // 私钥提取文件路径
  keyTwoText: null,
  keyThree: null
};
const defaultSignData = {
  done: false,
  btnFlag: false,
  module: null,
  parameter: null,
  signatureFilePath: null,
  promptFilePath: null,
  keyFilePath: null,
  stegoFilePath: null,
  // 认证结果
  verifyResult: null,
  extractingMessageFilePath: null,
  messageFile: null,
  message: null
};
const defaultUpload = {
  isUploadType: true,
  text: '',
  dom: null,
  showFileList: false,
  fileName: '',
  uploading: false
};

// ============> data <============
const appStore = useAppStore();
const taskForm = ref(null);
const shareKeyForm = ref(null);
const signForm = ref(null);
// 创建任务步骤的表单对象
const taskData = ref({
  done: false,
  createFlag: false,
  id: null,
  name: '',
  description: '',
  system: null,
  type: null,
  keyType: null,
  config: null,
  userID: null,
  targetUserId: null,
  // 上传公钥密文路径
  keyOneTextFilePath: null,
  keyOne: null
});
// 第二步共享密钥提取对象
const shareKey = ref({
  done: false,
  btnFlag: false,
  // 私钥提取文件路径
  keyTwoText: null,
  keyThree: null
});
const signData = ref({
  done: false,
  btnFlag: false,
  module: null,
  parameter: null,
  signatureFilePath: null,
  promptFilePath: null,
  keyFilePath: null,
  stegoFilePath: null,
  // 认证结果
  verifyResult: null,
  // ...
  extractingMessageFilePath: null,
  messageFile: null
});
// 上传控制对象
const uploadObj = ref({
  uploadUrl: `${import.meta.env.VITE_FILE_BASE_API}${uploadApi.uploadUrl}`,
  uploadRef(key){
    return function (dom){
      if (dom){
        uploadObj.value[key].dom = dom;
      }
    }
  },
  beforeUpload(key){
    return function (file){
      if (uploadObj.value[key].uploading){
        ElMessage.warning('当前有文件正在上传，请稍后重试');
        return false;
      }
      let extension = file.size < API.upload.commonLimit;
      if (!extension) {
        ElMessage.warning(`上传文件超过大小限制，文件须小于${API.upload.commonLimit / (1024 * 1024)}M`)
      }
      if (key === 'keyOneTextFilePath' || key === 'signatureFilePath'){
        let fileType = file.name.substring(file.name.lastIndexOf('.') + 1);
        extension = fileType == 'json' ? true : false;
        if (!extension){
          ElMessage.warning('上传文件须为json文件!');
        }
      }
      if (key === 'promptFilePath' || (key === 'stegoFilePath' && signData.value.module === '文本')){
        let fileType = file.name.substring(file.name.lastIndexOf('.') + 1);
        extension = fileType == 'txt' ? true : false;
        if (!extension){
          ElMessage.warning('上传文件须为txt文件!');
        }
      }
      if (key === 'keyFilePath'){
        let fileType = file.name.substring(file.name.lastIndexOf('.') + 1);
        extension = fileType == 'yaml' ? true : false;
        if (!extension){
          ElMessage.warning('上传文件须为yaml文件!');
        }
      }
      if (key === 'stegoFilePath' && signData.value.module === '图像') {
        let fileType = file.name.substring(file.name.lastIndexOf('.') + 1);
        extension = (fileType == 'jpg' || fileType == 'png' || fileType == 'jpeg') ? true : false;
        if (!extension){
          ElMessage.warning('上传文件须为jpg/png/jpeg文件!');
        }
      }
      if (key === 'stegoFilePath' && signData.value.module === '音频'){
        let fileType = file.name.substring(file.name.lastIndexOf('.') + 1);
        extension = (fileType == 'wav' || fileType == 'mp3') ? true : false;
        if (!extension){
          ElMessage.warning('上传文件须为wav/mp3文件!');
        }
      }
      uploadObj.value[key].fileName = extension ? file.name : '';
      uploadObj.value[key].showFileList = true;
      return extension;
    }
  },
  onSuccess(key, targetObj, form){
    return function (e){
      uploadObj.value[key].dom.clearFiles();
      uploadObj.value[key].showFileList = false;
      uploadObj.value[key].uploading = false;
      if (e.code === API.code.SUCCESS) { 
        ElMessage.success('上传成功');
        targetObj[key] = e.data.path;
      } else {
        let msg = e.msg || e.message || '上传失败，请稍后重试或联系管理员';
        ElMessage({
          type: 'error',
          duration: 1500,
          message: msg
        });
      }
      form.validateField([key]);
    }
  },
  onProgress(key){
    return function (e){
      uploadObj.value[key].showFileList = true;
      uploadObj.value[key].uploading = true;
    }
  },
  onError(key){
    return function (e){
      let message = e.msg || e.message || '上传失败，请稍后重试或联系管理员'
      ElMessage({
        type: 'error',
        duration: 1500,
        message
      });
      uploadObj.value[key].showFileList = false;
      uploadObj.value[key].uploading = false;
      uploadObj.value[key].dom.clearFiles();
      uploadObj.value[key].fileName = '';
    }
  },
  onRemove(key){
    return function (e){
      uploadObj.value[key].showFileList = false;
      uploadObj.value[key].uploading = false;
      uploadObj.value[key].dom.clearFiles();
      uploadObj.value[key].fileName = '';
    }
  },
  keyOneTextFilePath: {
    isUploadType: true,
    text: '',
    dom: null,
    showFileList: false,
    fileName: '',
    uploading: false
  },
  promptFilePath: {
    isUploadType: true,
    text: '',
    dom: null,
    showFileList: false,
    fileName: '',
    uploading: false
  },
  keyFilePath: {
    isUploadType: true,
    text: '',
    dom: null,
    showFileList: false,
    fileName: '',
    uploading: false
  },
  signatureFilePath: {
    isUploadType: true,
    text: '',
    dom: null,
    showFileList: false,
    fileName: '',
    uploading: false
  },
  stegoFilePath: {
    dom: null,
    showFileList: false,
    fileName: '',
    uploading: false
  }
});
// 表单验证规则
const rules = {
  name: rule.createRequired('任务名称不能为空'),
  keyType: rule.createRequired('请选择算法模块'),
  userID: rule.createRequired('请输入用户'),
  targetUserId: rule.createRequired('请输入目标用户'),
  // keyOneTextFilePath: rule.createRequired('请上传密钥密文', 'change'),
  keyOneTextFilePath: rule.createTextUpload(uploadObj.value, 'keyOneTextFilePath', '密钥密文不能为空'),
  module: rule.createRequired('请选择媒体类型'),
  // signatureFilePath: rule.createRequired('请上传签名文件', 'change'),
  signatureFilePath: rule.createTextUpload(uploadObj.value, 'signatureFilePath', '签名文件不能为空'),
  // promptFilePath: rule.createRequired('请上传提示词'),
  promptFilePath: rule.createTextUpload(uploadObj.value, 'promptFilePath', '提示词不能为空'),
  // keyFilePath: rule.createRequired('请上传协商密钥'),
  stegoFilePath: rule.createRequired('请上传载密文件')
};
const changeJSON = computed(() => {
  return function (jsonString){
    return jsonString ? window.decodeURIComponent(JSON.parse(jsonString)) : '';
  }
})
const getModuleShow = computed(() => {
  return function (url, module){
    let fileType = url.slice(url.lastIndexOf('.') + 1);
      let images = ['jpg', 'jpeg', 'png', 'bmp'],
          audios = ['mp3', 'wav', 'flac'],
          txts = ['txt'],
          moduleType;
      if (txts.includes(fileType)) {
        moduleType = '文本'; 
      } else if (images.includes(fileType)){
        moduleType = '图像';
      } else {
        moduleType = '音频';
      }
      return moduleType;
  }
})



// ============> hooks <============
onActivated(() => {
  let { id, isCreate, reenter } = route.query;
  if (reenter || (id !== undefined && id == taskData.value.id)){
    return;
  }
  if (isCreate){
    init();
    return;
  }
  reInit();
});


// ============> methods <============
function init(){
  taskData.value = Object.assign({}, defaultTaskData);
  shareKey.value = Object.assign({}, defaultShareKey);
  signData.value = Object.assign({}, defaultSignData);
  uploadObj.value.keyOneTextFilePath = Object.assign({}, defaultUpload);
  uploadObj.value.signatureFilePath = Object.assign({}, defaultUpload);
  uploadObj.value.promptFilePath = Object.assign({}, defaultUpload);
  uploadObj.value.keyFilePath = Object.assign({}, defaultUpload);
  uploadObj.value.stegoFilePath = Object.assign({}, defaultUpload);
}
function reInit(){
  let {id} = route.query;
  init();
  request.getTaskDetailById({id})
    .then(res => {
      let result = res;
      result.infoData = JSON.parse(res.infoData);
      taskData.value.id = result.id;
      taskData.value.name = result.name;
      taskData.value.description = result.description;
      taskData.value.keyType = result.infoData.keyType;
      taskData.value.config = result.infoData.config;
      taskData.value.userID = result.infoData.userID;
      taskData.value.targetUserId = result.infoData.targetUserId;
      if (result.infoData && result.infoData.keyOne){
        taskData.value.done = true;
        taskData.value.createFlag = false;
        taskData.value.keyOneTextFilePath = result.infoData.keyOneTextFilePath;
        taskData.value.keyOne = result.infoData.keyOne;
        uploadObj.value.keyOneTextFilePath.fileName = 'keyOne.json';
        uploadObj.value.keyOneTextFilePath.text = result.infoData.keyOne;
      }

      if (result.infoData && result.infoData.keyThree && result.infoData.keyTwoText){
        shareKey.value.done = true;
        shareKey.value.btnFlag = false;
        shareKey.value.keyThree = result.infoData.keyThree;
        shareKey.value.keyTwoText = result.infoData.keyTwoText;
      }
      if (result.infoData && result.infoData.verifyResult !== null && result.infoData.verifyResult !== undefined){
        signData.value.done = true;
        signData.value.btnFlag = false;
        signData.value.module = result.infoData.module;
        signData.value.parameter = result.infoData.parameter;

        signData.value.signatureFilePath = result.infoData.signatureFilePath;
        signData.value.promptFilePath = result.infoData.promptFilePath;
        signData.value.keyFilePath = result.infoData.keyFilePath;
        signData.value.stegoFilePath = result.infoData.stegoFilePath;
        uploadObj.value.signatureFilePath.fileName = 'signature.json';
        uploadObj.value.promptFilePath.fileName = 'prompt.txt';
        uploadObj.value.keyFilePath.fileName = 'key.yaml';
        let messageName = 'stego';
        switch (result.infoData.module){
          case '图像':
            messageName += '.png';
            break;
          case '文本':
            messageName += '.txt';
            break;
          case '音频':
            messageName += '.wav';
            break;
        }
        uploadObj.value.stegoFilePath.fileName = messageName;
        signData.value.verifyResult = result.infoData.verifyResult;
        signData.value.extractingMessageFilePath = result.infoData.extractingMessageFilePath;
        uploadApi.download({filePath: result.infoData.extractingMessageFilePath})
          .then(res => {
            let moduleType = getModuleShow.value(signData.value.extractingMessageFilePath, signData.value.module);
            if (moduleType === '图像') {
              signData.value.messageFile = window.URL.createObjectURL(res.data);
            } else if (moduleType === '音频'){
              let origin = signData.value.extractingMessageFilePath,
                  index;
              if (origin.lastIndexOf('\\') > 0){
                index = origin.lastIndexOf('\\');
              } else if (origin.lastIndexOf('/') > 0){
                index = origin.lastIndexOf('/');
              }
              signData.value.messageFile = origin.slice(index + 1);
            } else {
              let reader = new FileReader();
              reader.readAsText(res.data, 'UTF-8');
              reader.onload= function(evt){
                signData.value.messageFile = evt.target.result || ''
              }
            }
          })
      }
    })
}
function changeUploadType(key, data){
  if (data && data.done){
    return;
  }
  uploadObj.value[key].isUploadType = !uploadObj.value[key].isUploadType;
  uploadObj.value[key].text = '';
  uploadObj.value[key].showFileList = false;
  uploadObj.value[key].fileName = '';
  uploadObj.value[key].uploading = false;
  data[key] = null;
}
function clearData(key, data){
  data[key] = '';
}
function createBlobTxt(e, key, data, form){
  if (!e){
    data[key] = null;
    ElMessage.success('上传成功');
    return;
  }
  let fileType, filename;
  switch (key){
    case 'keyOneTextFilePath':
      filename = 'keyOneText.json';
      fileType = 'application/json';
      break;
    case 'signatureFilePath':
      filename = 'signature.json';
      fileType = 'application/json';
      break;
    case 'promptFilePath':
      filename = 'prompt.txt';
      fileType = 'text/plain';
      break;
  }
  const blob = new Blob([e], { type: fileType});
  const file = new File([blob], filename, { type: fileType});
  let formData = new FormData();
  formData.append('file', file);
  uploadApi.upload(formData)
    .then(res => {
      ElMessage.success('上传成功');
      data[key] = res.path;
      uploadObj.value[key].fileName = filename;
      form.validateField([key])
    })
    .catch(err => {
      console.log(err);
      let msg = err.msg || err.message || '上传失败，请稍后重试或联系管理员';
      ElMessage.error(msg);
      form.validateField([key])
    })
}
// 通用复制
function copyText(key, data, warning = '内容为空，请稍后重试或联系管理员'){
  if (!data[key]) {
    ElMessage.warning(warning);
    return;
  }
  if (navigation.clipboard){
    navigation.clipboard.writeText(data[key])
      .then(res => {
        ElMessage.success('已复制到剪切板');
      })
      .catch(err => {
        ElMessage.error('复制失败');
      })
  } else if (document.execCommand){
    const textarea = document.createElement('textarea');
    textarea.value = data[key];
    document.body.appendChild(textarea);
    textarea.select();
    try {
      const successful = document.execCommand('copy');
      if (successful){
        ElMessage.success('已复制到剪切板');
      } else {
        ElMessage.error('复制失败');
      }
    } catch(err){
      ElMessage.error(err);
    }
    document.body.removeChild(textarea); 
  }
}
// 通用下载
function downText(key, data, warning = '下载内容为空，请稍后再试或联系管理员', filename){
  if (!data[key]){
    ElMessage.warning(warning);
    return;
  }
  const blob = new Blob([data[key]], { type: 'application/json' });
  const link = document.createElement('a');
  const fileUrl = window.URL.createObjectURL(blob);
  link.href = fileUrl;
  link.download = filename;
  ElMessage.success('下载开始');
  link.click();
  window.URL.revokeObjectURL(fileUrl);
}
function downloadFile(){
  uploadApi.download({ filePath: signData.value.extractingMessageFilePath})
    .then(res => {
      let fileUrl = window.URL.createObjectURL(res.data);
      // if (signData.value.module === '图像' || signData.value.module === '音频'){
      //   signData.value.messageFile = fileUrl;
      //   console.log(signData.value.messageFile);
      // } else {
      //   let reader = new FileReader();
      //   reader.readAsText(res.data, 'UTF-8');
      //   reader.onload= function(evt){
      //     signData.value.messageFile = evt.target.result || ''
      //     console.log(signData.value.messageFile);
      //   }
      // }
      let a = document.createElement('a');
          // disposition = res.headers['content-disposition'],
          // filename = disposition.slice(disposition.lastIndexOf('=') + 1);
      let origin = signData.value.extractingMessageFilePath,
          index;
      if (origin.lastIndexOf('\\') > 0){
        index = origin.lastIndexOf('\\');
      } else if (origin.lastIndexOf('/') > 0){
        index = origin.lastIndexOf('/');
      }
      let filename = origin.slice(index + 1);
      a.href = fileUrl;
      a.download = filename;
      a.click();
    })
    .catch(err => {
      let message = err.msg || err.message || err.data.msg || '下载失败，请稍后重试或联系管理员';
      ElMessage.error(message);
    })
}
function moduleChange(){
  signData.value.stegoFilePath = null;
  uploadObj.value.stegoFilePath.fileName = '';
  uploadObj.value.stegoFilePath.dom.clearFiles();
}
function handleCancel(){
  router.back();
}
// 第一步 - 公钥提取
function handleCreate(){
  if (taskData.value.createFlag){
    ElMessage.warning('当前正在执行解密密钥，请稍后');
    return;
  }
  taskForm.value.validate(valid => {
    if (valid){
      taskData.value.createFlag = true;
      appStore.openLoading('解密密钥...');
      request.applicationOneExtractPublicKey({
        name: taskData.value.name,
        moduleType: API.steganography.moduleType.APPONE,
        taskType: API.steganography.type.EXTRACT,
        description: taskData.value.description,
        infoData: {
          targetUserId: taskData.value.targetUserId,
          userID: taskData.value.userID,
          keyType: taskData.value.keyType,
          config: taskData.value.config,
          keyOneTextFilePath: taskData.value.keyOneTextFilePath
        }
      })
        .then(res => {
          taskData.value.createFlag = false;
          appStore.closeLoading();
          if (res && res.infoData && res.infoData.keyOne){
            ElMessage.success('密钥解密成功');
            taskData.value.id = res.id;
            taskData.value.keyOne = res.infoData.keyOne;
            taskData.value.done = true;
          } else {
            ElMessage.error('密钥解密失败，请稍后重试或联系管理员');
          }
        })
        .catch(err => {
          console.log(err);
          appStore.closeLoading();
          taskData.value.createFlag = false;
        })
    } else {
      ElMessage.warning('填写信息有误，请核对后提交');
    }
  })
}
// 第二步 - 提取私钥
function handleShareKey(){
  if (shareKey.value.btnFlag){
    ElMessage.warning('当前正在进行参数发送，请稍后');
    return;
  }
  shareKey.value.btnFlag = true;
  appStore.openLoading('参数发送...');
  request.applicationOneExtractSharedKey({id: taskData.value.id})
    .then(res => {
      shareKey.value.btnFlag = false;
      appStore.closeLoading();
      if (res && res.infoData && res.infoData.keyTwoText && res.infoData.keyThree){
        ElMessage.success('参数发送成功');
        shareKey.value.keyTwoText = res.infoData.keyTwoText;
        shareKey.value.keyThree = res.infoData.keyThree;
        shareKey.value.done = true;
      } else {
        ElMessage.error('参数发送失败，请稍后重试或联系管理员');
      }
    })
    .catch(err => {
      console.log(err)
      appStore.closeLoading();
      shareKey.value.btnFlag = false;
    })
}
// 第三步 - 提取签名
function handleSign(){
  // if (signData.value.btnFlag){
  //   ElMessage.warning('当前正在进行签名认证、信息提取，请稍后');
  //   return;
  // }
  signForm.value.validate(valid => {
    if (valid){
      signData.value.btnFlag = true;
      appStore.openLoading('签名认证、信息提取中...');
      request.applicationOneExtractSign({
        id: taskData.value.id,
        name: taskData.value.name,
        moduleType: API.steganography.moduleType.APPONE,
        taskType: API.steganography.type.EXTRACT,
        description: taskData.value.description,
        infoData: {
          targetUserId: taskData.value.targetUserId,
          userID: taskData.value.userID,
          keyType: taskData.value.keyType,
          config: taskData.value.config,
          publicKeyTextFilePath: taskData.value.publicKeyTextFilePath,
          encryptedSharedKeyFilePath: shareKey.value.encryptedSharedKeyFilePath,
          signatureFilePath: signData.value.signatureFilePath,
          promptFilePath: signData.value.promptFilePath,
          // keyFilePath: signData.value.keyFilePath,
          stegoFilePath: signData.value.stegoFilePath,
          module: signData.value.module,
          parameter: signData.value.parameter
        }
      })
        .then(res => {
          signData.value.btnFlag = false;
          appStore.closeLoading();
          if (res && res.infoData && res.infoData.verifyResult){
            ElMessage.success('签名认证、信息提取成功');
            signData.value.verifyResult = res.infoData.verifyResult;
            signData.value.done = true;
            // 做签名媒体文件的回显
            if (res.infoData.extractingMessageFilePath) {
              signData.value.extractingMessageFilePath = res.infoData.extractingMessageFilePath;
              uploadApi.download({ filePath: signData.value.extractingMessageFilePath})
                .then(result => {
                  // console.log(result);
                  // let reader = new FileReader();
                  // reader.readAsText(result.data, 'UTF-8');
                  // reader.onload= function(evt){
                  //   signData.value.messageFile = evt.target.result || ''
                  //   console.log(signData.value.messageFile);
                  // }

                  let moduleType = getModuleShow.value(signData.value.extractingMessageFilePath, signData.value.module);
                  if (moduleType === '图像') {
                    signData.value.messageFile = window.URL.createObjectURL(result.data);
                  } else if (moduleType === '音频'){
                    let origin = signData.value.extractingMessageFilePath,
                        index;
                    if (origin.lastIndexOf('\\') > 0){
                      index = origin.lastIndexOf('\\');
                    } else if (origin.lastIndexOf('/') > 0){
                      index = origin.lastIndexOf('/');
                    }
                    signData.value.messageFile = origin.slice(index + 1);
                  } else {
                    let reader = new FileReader();
                    reader.readAsText(result.data, 'UTF-8');
                    reader.onload= function(evt){
                      signData.value.messageFile = evt.target.result || ''
                    }
                  }
                  // if (signData.value.module === '图像' || signData.value.module === '音频'){
                  //   // todo - 这里要做ObjectURL的释放
                  //   signData.value.messageFile = window.URL.createObjectURL(result.data);
                  //   console.log(signData.value.messageFile);
                  // } else {
                  //   let reader = new FileReader();
                  //   console.log(reader)
                  //   reader.readAsText(res.data, 'UTF-8');
                  //   reader.onload= function(evt){
                  //     signData.value.messageFile = evt.target.result || ''
                  //     console.log(signData.value.messageFile);
                  //   }
                  // }
                })
            }
          } else {
            ElMessage.error('签名认证、信息提取失败，请稍后重试或联系管理员');
          }
        })
        .catch(err => {
          console.log(err)
          appStore.closeLoading();
          signData.value.btnFlag = false;
        })
    } else {
      ElMessage.warning('填写信息有误，请核对后提交');
      signData.value.btnFlag = false;
    }
  })
}

</script>
<style lang='scss' scoped>
@import '@/assets/styles/mixin.scss';
.row-between {
  justify-content: space-between;
}
.item-3 {
  width: 30%
}
.item-5 {
  width: 49%;
  // height: auto;
  // padding: 50px 0 60px 0;
}
.item-10 {
  width: 100%;
  height: auto;
  padding: 20px 0;
  .condition-label {
    width: 15%;
  }
  .condition-input {
    width: 80%;
  }
}
.item-10-spe {
  width: 100%;
  .condition-label {
    width: 15%;
  }
  .condition-input {
    width: 80%;
  }
  &::v-deep .el-form-item__content {
    align-items: center!important;
  }
}
.data-title-between {
  @include flex-between-center;
  .data-title-actions {
    display: flex;
  }
}
.btn-groups {
  margin-top: 20px;
  text-align: center;
  .btn {
    margin: 0 20px;
  }
}
.item-upload {
  padding-bottom: 50px;
}
.upload {
  width: 100%;
  min-height: 120px;
  height: 120px;
  &::v-deep .el-upload {
    @include wh-100;
    // height: 100%!important;
    .el-upload-dragger {
      @include wh-100;
      border-color: var(--color-main);
      padding: 0;
      .upload-empty {
        @include wh-100;
        @include flex-all-center;
        flex-direction: column;
        .upload-icon {
          font-size: 30px;
          color: var(--color-gray-10);
        }
        .upload-des {
          color: var(--color-gray-10);
        }
      }
      .upload-content {
        @include wh-100;
        @include flex-all-center;
        flex-direction: column;
        .upload-icon {
          font-size: 30px;
          color: var(--color-main);
        }
        .upload-des {
          color: var(--color-main);
        }
      }
    }
  }
}
.condition-label-change {
  cursor: pointer;
}
.condition-label-change:hover {
  color: var(--color-primary);
}
.audio-container {
  width: 100%;
  height: 190px;
  background-color: var(--color-gray-2);
  border: 1px solid var(--color-main-border);
  border-radius: 6px;
  position: relative;
  overflow: hidden;
  @include flex-all-center;
  .audio-icon {
    font-size: 40px;
    font-weight: bolder;
    color: var(--color-main);
  }
  .audio {
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 105%;
    height: 30px;
    transform: translateX(-50%);
  }
}
.audio-show {
  @include flex-all-center;
  flex-direction: column;
}
.data-table-scroll {
  max-height: 220px;
  height: auto;
  overflow-y: auto;
  @include scrollBar;
  .file-image {
    width: 100%;
    height: 190px;
    background-color: var(--color-gray-2);
    border: 1px solid var(--color-main-border);
    border-radius: 6px;
  }
}
</style>